# -*- coding:utf-8 -*-

import json
import time
import requests
from tkinter import *

from PIL import Image, ImageTk

week_dict = {
    0: '星期日',
    1: '星期一',
    2: '星期二',
    3: '星期三',
    4: '星期四',
    5: '星期五',
    6: '星期六',
}

# from http://www.51yuansu.com/sc/vvqkfxzkmo.html
# from http://www.weather.com.cn/static/html/legend.shtml
icon_dict = {
    '晴': 'assets/01_sunny.png',
    '多云': 'assets/02_cloudy.png',
    '阴': 'assets/03_overcast.png',
    '阵雨': 'assets/04_shower.png',
    '雷阵雨': 'assets/05_thundershower.png',
    '雷阵雨伴有冰雹': 'assets/06_thundershowerwithhail.png',
    '雨夹雪': 'assets/07_sleet.png',
    '小雨': 'assets/08_lightrain.png',
    '中雨': 'assets/09_moderaterain.png',
    '大雨': 'assets/10_heavyrain.png',
    '暴雨': 'assets/11_rainstorm.png',
    '大暴雨': 'assets/12_downpour.png',
    '特大暴雨': 'assets/13_heavydownpour.png',
    '阵雪': 'assets/14_snowshower.png',
    '小雪': 'assets/15_lightsnow.png',
    '中雪': 'assets/16_moderatesnow.png',
    '大雪': 'assets/17_heavysnow.png',
    '暴雪': 'assets/18_heavysnowfall.png',
    '雾': 'assets/19_fog.png',
    '冻雨': 'assets/20_icerain.png',
    '沙尘暴': 'assets/21_sandstorm.png',
    '浮尘': 'assets/22_floatingdust.png',
    '扬沙': 'assets/23_sandblowing.png',
    '强沙尘暴': 'assets/24_heavysandstorm.png',
    '霾': 'assets/25_haze.png',
    '小雨-中雨': 'assets/09_moderaterain.png',
    '中雨-大雨': 'assets/10_heavyrain.png',
    '大雨-暴雨': 'assets/11_rainstorm.png',
    '暴雨-大暴雨': 'assets/12_downpour.png',
    '大暴雨-特大暴雨': 'assets/13_heavydownpour.png',
    '小雪-中雪': 'assets/16_moderatesnow.png',
    '中雪-大雪': 'assets/17_heavysnow.png',
    '大雪-暴雪': 'assets/18_heavysnowfall.png',
}

weather_list = [
    {'date': '', 'high': '', 'low': '', 'type': '', 'wdir': '', 'wpwr': ''},  # today
    {'date': '', 'high': '', 'low': '', 'type': '', 'wdir': '', 'wpwr': ''},  # tomorrow
    {'date': '', 'high': '', 'low': '', 'type': '', 'wdir': '', 'wpwr': ''},  # the day after tomorrow
    {'date': '', 'high': '', 'low': '', 'type': '', 'wdir': '', 'wpwr': ''},  # three days from now
]

# font_default = 'Helvetica'
font_default = '华文楷体'
time_format = 12  # 12 or 24

xlarge_text_size = 94
large_text_size = 48
medium_text_size = 28
small_text_size = 18

pad_x = 100
pad_x_icon = 20
pad_y = 60
icon_w = 100
icon_h = 100


class Clock(Frame):
    def __init__(self, parent, *args, **kwargs):
        Frame.__init__(self, parent, bg='black')
        # initialize time label
        self.time = ''
        self.timeLbl = Label(self, font=(font_default, large_text_size), fg="white", bg="black")
        self.timeLbl.pack(side=TOP, anchor=E)
        # initialize day of week
        self.week = ''
        self.dayOWLbl = Label(self, text=self.week, font=(font_default, small_text_size), fg="white", bg="black")
        self.dayOWLbl.pack(side=TOP, anchor=E)
        # initialize date label
        self.date = ''
        self.dateLbl = Label(self, text=self.date, font=(font_default, small_text_size), fg="white", bg="black")
        self.dateLbl.pack(side=TOP, anchor=E)
        self.tick()

    def tick(self):
        if time_format == 12:
            time_new = time.strftime('%I:%M %p')  # hour in 12h format
        else:
            time_new = time.strftime('%H:%M')  # hour in 24h format
        if time_new != self.time:
            self.time = time_new
            self.timeLbl.config(text=time_new)

        week_idx = int(time.strftime("%w"))
        week_new = time.strftime('{d}%U{z}{s}{x}').format(d='第', z='周', s='  ', x=week_dict.get(week_idx))
        if week_new != self.week:
            self.week = week_new
            self.dayOWLbl.config(text=week_new)

        date_new = time.strftime('%Y{y}%m{m}%d{d}').format(y='年', m='月', d='日')
        if date_new != self.date:
            self.date = date_new
            self.dateLbl.config(text=date_new)

        # calls itself every 200 milliseconds
        # to update the time display as needed
        # could use >200 ms, but display gets jerky
        self.timeLbl.after(200, self.tick)


class Weather(Frame):
    def __init__(self, parent, *args, **kwargs):
        Frame.__init__(self, parent, bg='black')
        self.temperature = ''
        self.icon = ''
        self.city = ''
        self.wd_list = weather_list
        self.forecast = ''
        self.health = ''

        self.degreeFrm = Frame(self, bg="black")
        self.degreeFrm.pack(side=TOP, anchor=W)

        self.temperatureLbl = Label(self.degreeFrm, font=(font_default, xlarge_text_size), fg="white", bg="black")
        self.temperatureLbl.pack(side=LEFT, anchor=N)
        self.iconLbl = Label(self.degreeFrm, bg="black")
        self.iconLbl.pack(side=LEFT, anchor=N, padx=pad_x_icon)

        self.locationLbl = Label(self, font=(font_default, medium_text_size), fg="white", bg="black")
        self.locationLbl.pack(side=TOP, anchor=W)
        self.typeLbl = Label(self, font=(font_default, medium_text_size), fg="white", bg="black")
        self.typeLbl.pack(side=TOP, anchor=W)
        self.windLbl = Label(self, font=(font_default, medium_text_size), fg="white", bg="black")
        self.windLbl.pack(side=TOP, anchor=W)
        self.healthLbl = Label(self, font=(font_default, small_text_size), justify='left', fg="white", bg="black")
        self.healthLbl.pack(side=TOP, anchor=W)
        self.forecastLbl = Label(self, font=(font_default, small_text_size), justify='left', fg="white", bg="black")
        self.forecastLbl.pack(side=TOP, anchor=W)
        self.get_weather()

    def get_location(self):
        try:
            response = requests.get('http://pv.sohu.com/cityjson')
            # print(response.status_code)
            if response.status_code == 200:
                print(response.text)
                location = response.text.split('=')[1].split(',')[2].split('"')[3]  # 取出地址信息
                # print(location)
                if '省' in location:
                    province = location.split('省')[0] + '省'
                    city = location.split('省')[1]
                else:
                    province = location
                    city = location
                # print(province, city)
                return province, city
            else:
                return 'ERROR_REQ'
        except Exception as e:
            return 'ERROR_EXP'

    def get_weather(self):
        get_status = ''
        location = self.get_location()
        if location == 'ERROR_REQ' or location == 'ERROR_EXP':
            # print('ERROR_LOC')
            get_status = 'ERROR_LOC'
        else:
            try:
                self.city = location[1]
                response = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=' + self.city)
                # print(response.status_code)
                if response.status_code == 200:
                    print(response.text)
                    weather_json = json.loads(response.text)
                    if weather_json['status'] == 1000:
                        get_status = 'OK'
                        data = weather_json['data']
                        self.temperature = data['wendu']
                        self.health = data['ganmao'].replace('。', '。\n')
                        forecast = data['forecast']
                        for idx in range(0, len(self.wd_list)):
                            self.wd_list[idx]['date'] = forecast[idx]['date']  # .split('星')[0]
                            self.wd_list[idx]['high'] = forecast[idx]['high'].split(' ')[1]
                            self.wd_list[idx]['low'] = forecast[idx]['low'].split(' ')[1]
                            self.wd_list[idx]['type'] = forecast[idx]['type']
                            self.wd_list[idx]['wdir'] = forecast[idx]['fengxiang']
                            self.wd_list[idx]['wpwr'] = forecast[idx]['fengli'].split('[')[2].split(']')[0]
                        # print(self.temperature, self.health, self.wd_list)

                    else:
                        get_status = 'ERROR_API'
                else:
                    get_status = 'ERROR_REQ'
            except Exception as e:
                get_status = 'ERROR_EXP'
        print('status: ' + get_status)

        try:
            if get_status == 'OK':
                self.temperatureLbl.config(text=self.temperature + '℃')
                self.locationLbl.config(text=self.city)
                # today
                type_text = self.wd_list[0]['type'] + ' ' + self.wd_list[0]['low'] + '-' + self.wd_list[0]['high']
                self.typeLbl.config(text=type_text)
                wind_text = self.wd_list[0]['wdir'] + ' 风力' + self.wd_list[0]['wpwr']
                self.windLbl.config(text=wind_text)
                self.healthLbl.config(text=self.health)
                forecast_text = ''
                for idx in range(1, len(self.wd_list)):
                    forecast_text += self.wd_list[idx]['date'] \
                                     + '：' + self.wd_list[idx]['type'] \
                                     + '  ' + self.wd_list[idx]['low'] + '-' + self.wd_list[idx]['high'] \
                                     + '  ' + self.wd_list[idx]['wdir'] + ' 风力' + self.wd_list[idx]['wpwr'] \
                                     + '\n'
                self.forecastLbl.config(text=forecast_text)

                weather_type = self.wd_list[0]['type']
                if weather_type in icon_dict:
                    self.icon = icon_dict[weather_type]
                else:
                    self.icon = ''
                if self.icon != '':
                    image = Image.open(self.icon)
                    image = image.resize((icon_w, icon_h), Image.ANTIALIAS)
                    image = image.convert('RGB')
                    photo = ImageTk.PhotoImage(image)
                    self.iconLbl.config(image=photo)
                    self.iconLbl.image = photo
                else:
                    pass
                self.after(3600000, self.get_weather)   # 60mins
            elif get_status == 'ERROR_LOC':  # location
                self.locationLbl.config(text='正在获取位置...')
                self.after(20000, self.get_weather)     # 20s
            elif get_status == 'ERROR_API':  # weather
                self.locationLbl.config(text=self.city)
                self.typeLbl.config(text='正在获取天气...')
                self.after(20000, self.get_weather)     # 20s
            elif get_status == 'ERROR_REQ' or get_status == 'ERROR_EXP':  # weather
                self.after(10000, self.get_weather)     # 10s
            else:
                # impossible
                self.after(600000, self.get_weather)    # 10mins
        except Exception as e:
            print('ERROR_EXP')
            self.after(10000, self.get_weather)         # 10s


class Window:
    def __init__(self):
        self.tk = Tk()
        self.tk.configure(bg='black')
        self.tk.attributes("-fullscreen", True)  # 全屏
        self.isFullScreen = True
        w = self.tk.winfo_screenwidth()
        h = self.tk.winfo_screenheight()
        print('screen resolution: ', w, h)
        # w = w /2.5
        # self.tk.attributes("-topmost", True)       # 置顶
        # self.tk.overrideredirect(True)             # 无标题栏
        # self.tk.geometry("%dx%d" % (w, h))         # 半屏

        if w < 1364:
            global xlarge_text_size, large_text_size, medium_text_size, small_text_size
            xlarge_text_size = int(w/15)
            large_text_size = int(w/28)
            medium_text_size = int(w/48)
            small_text_size = int(w/73)
            global pad_x, pad_x_icon, pad_y, icon_w, icon_h
            pad_x = int(w/26)
            pad_x_icon = int(w/68)
            pad_y = int(w/32)
            icon_w = int(w/12)
            icon_h = int(w/12)
        else:
            pass

        self.tk.bind("<Return>", self.toggle_fullscreen)
        self.tk.bind("<Escape>", self.terminate_window)
        self.tk.bind("<Double-Button-1>", self.terminate_window)  # 鼠标左键双击

        self.topFrame = Frame(self.tk, bg='black')
        self.bottomFrame = Frame(self.tk, bg='black')
        self.topFrame.pack(side=TOP, fill=BOTH, expand=YES)
        self.bottomFrame.pack(side=BOTTOM, fill=BOTH, expand=YES)

        # clock
        self.clock = Clock(self.topFrame)
        self.clock.pack(side=RIGHT, anchor=N, padx=pad_x, pady=pad_y)
        # weather
        self.weather = Weather(self.topFrame)
        self.weather.pack(side=LEFT, anchor=N, padx=pad_x, pady=pad_y)
        # # news
        # self.news = News(self.bottomFrame)
        # self.news.pack(side=LEFT, anchor=S, padx=100, pady=60)
        # calender - removing for now
        # self.calender = Calendar(self.bottomFrame)
        # self.calender.pack(side = RIGHT, anchor=S, padx=100, pady=60)

    def toggle_fullscreen(self, event=None):
        self.isFullScreen = not self.isFullScreen  # Just toggling the boolean
        self.tk.attributes("-fullscreen", self.isFullScreen)
        return "break"

    def terminate_window(self, event=None):
        self.tk.destroy()
        return "break"


if __name__ == '__main__':
    w = Window()
    w.tk.mainloop()
